/**
 * 
 */
package com.FBTI.free.calc;

//imports
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.*;

/**
 * @author Alfredo Baganha
 *
 */
public class RPNStack {



	/**
	 * 
	 */
	
	//globals
	private Stack<Double> stack;
	
	//constructor
	public RPNStack() {
		stack= new Stack<Double>();
		stack.setSize(10);
		stack.ensureCapacity(5);
	}
	
	//swaps the element at top of stack with the element at specified index
	public void swapElements(int index)throws EmptyStackException, SizeException{
		if(stack.isEmpty()){
			throw new EmptyStackException();
		}else if(index>stack.size()){
			throw new SizeException();
		}else{
			double topVal, swapVal;
			int len=stack.size()-2;
			double list[]=new double[len];
			topVal=stack.pop();
			for(int i=list.length-1;i>=0;i--){
				list[i]=stack.pop();
			}
			swapVal=stack.pop();
			stack.push(topVal);
			for(int i=0;i<list.length;i++){
				stack.push(list[i]);
			}
			stack.push(swapVal);
			list= null;
		}
	
	}
	
	//removes the element at top of stack
	public void remove()throws EmptyStackException{
		if(stack.isEmpty()){
			throw new EmptyStackException();
		}else{
			stack.pop();
		}
	}
	
	//duplicates the element at top of stack
	public void duplicate()throws EmptyStackException{
		if(stack.isEmpty()){
			throw new EmptyStackException();
		}else{
			double val=stack.pop();
			stack.push(val);
			stack.push(val);
		}
		
	}
	
	//rotates the stack 
	public void rotate()throws EmptyStackException,SizeException{
		if(stack.isEmpty()){
			throw new EmptyStackException();
		}else if(stack.size()<2){
			throw new SizeException();
		}else{
			double topVal;
			int len=stack.size()-1;
			double list[]=new double[len];
			topVal=stack.pop();
			for(int i=list.length-1;i>=0;i--){
				list[i]=stack.pop();
			}
			stack.push(topVal);
			for(int i=0;i<list.length;i++){
				stack.push(list[i]);
			}
			list= null;
		}
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((stack == null) ? 0 : stack.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		RPNStack other = (RPNStack) obj;
		if (stack == null) {
			if (other.stack != null)
				return false;
		} else if (!stack.equals(other.stack))
			return false;
		return true;
	}
	
	
	private class SizeException extends Exception{

		/**
		 * 
		 */
		private static final long serialVersionUID = 3556699400432898411L;

		@Override
		public Throwable getCause() {
			// TODO Auto-generated method stub
			return super.getCause();
		}

		@Override
		public String getMessage() {
			// TODO Auto-generated method stub
			return super.getMessage();
		}

		@Override
		public void printStackTrace() {
			// TODO Auto-generated method stub
			super.printStackTrace();
		}

		@Override
		public void printStackTrace(PrintStream err) {
			// TODO Auto-generated method stub
			super.printStackTrace(err);
		}

		@Override
		public void printStackTrace(PrintWriter err) {
			// TODO Auto-generated method stub
			super.printStackTrace(err);
		}
		
	}


}

